from strategy.StrategyTemplate import StrategyTemplate
from strategy import strategy_filter
from strategy.pro_strategy.pro_strategy_common import double_column
import pandas as pd
from utils.db import DbHandler


class DoubleLow(StrategyTemplate):
    """
    yyb凌波的年化收益47%双低转债策略
        集思录双低值 = 转债价格+转股溢价率×100，越低越好

        富投网双低值 = 2×转债价格-转股价值，越低越好

        默认排名是富投网的双低值，排除掉1年内到期和已经公告强赎的转债

        建仓方法:

            双低均值低于160时开始建仓，低于155，150时逐步加仓
        买入方法:

            平均买入筛选后的前 10 或前 15 只双低转债
        卖出方法:

            每月轮动，公告强赎后第5个交易日卖出
        详细介绍: 双低策略

    """
    def __init__(self):
        super(self.__class__, self).__init__()
        self.strategy_name = "启四双低策略"
        self.strategy_descrption = "按涨幅排序"

    def run(self):
        # 基础过滤，过滤掉新债、强赎、EB
        self.data = strategy_filter.filter_base(self.data)
        # 到期时间大于一年
        self.data = self.data.loc[self.data['剩余年限'] >= 1.0]

        self.data['富投评分'] = round(2 * self.data['现价'] - self.data['转股价值'],3)
        self.data['集思录评分'] = round(self.data['现价'] + self.data['溢价率'],3)
        self.data = self.data.sort_values(by='富投评分', ascending=True)
        self.data = self.data[['转债名称', '转债代码', '现价', '剩余年限', '溢价率', '到期税前收益',
                               '剩余规模', '集思录评分', '富投评分', '行业']][:20]
        # 清掉原来的索引
        self.data.reset_index(inplace=True, drop=True)

    def api(self, size=10):
        db = DbHandler()
        db.create_session()
        super(self.__class__, self).api(db=db)

        self.data = self.data.loc[self.data['year_left'] >= 1.0]

        self.data['ft_score'] = round(2 * self.data['price'] - self.data['convert_value'], 3)
        self.data['jsl_score'] = round(self.data['price'] + self.data['premium_rt'], 3)
        self.data = self.data.sort_values(by='jsl_score', ascending=True)
        self.data = self.data[double_column][:size]
        # 清掉原来的索引
        self.data.reset_index(inplace=True, drop=True)
        self.db.close_session()
        return self.data

if __name__ == '__main__':
    ins = DoubleLow()
    ins.topN = 20
    ins.test()

